from python_ai.common.xcommon import sep
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler

tf.compat.v1.set_random_seed(777)

sep('Load data')
data = np.loadtxt(r'../../../ML/lin_regression/data/ex1data1.txt', delimiter=',')
print(data[:5])

data = StandardScaler().fit_transform(data)

x_data = data[:, 0]
y_data = data[:, -1]

sep('Placeholder')
x = tf.compat.v1.placeholder(tf.float32, shape=[None])
y = tf.compat.v1.placeholder(tf.float32, shape=[None])

sep('w and b')
# w = tf.Variable(tf.random.normal([1]), name='weight')
# b = tf.Variable(tf.random.normal([1]), name='bias')
w = tf.Variable(0., name='weight')
b = tf.Variable(0., name='bias')

sep('model')
h = x * w + b

sep('cost')
# 越过最低点的情况，看来缩放在单变量时也是必要的
# If *2 rather than /2, alpha 0.01 is too large without Standardarization!
# cost = tf.reduce_mean(tf.square(h - y)) / tf.constant(2.)
cost = tf.reduce_mean(tf.square(h - y)) / 2.  # also OK

sep('train')
train = tf.compat.v1.train.GradientDescentOptimizer(learning_rate=0.01)\
    .minimize(cost)

sep('Session')
with tf.compat.v1.Session() as sess:
    sess.run(tf.compat.v1.global_variables_initializer())

    iters = 200
    group = iters // 10
    j_his = np.zeros(iters)
    for i in range(iters):
        cost_v, w_v, b_v, _ = sess.run([cost, w, b, train],
                                       feed_dict={x: x_data,
                                                  y: y_data},
                                       )
        j_his[i] = cost_v
        if i % group == 0:
            print(f'#{i + 1} cost = {cost_v}, w = {w_v}, b = {b_v}')
    if i % group != 0:
        print(f'#{i + 1} cost = {cost_v}, w = {w_v}, b = {b_v}')

sep('figure')
plt.figure(figsize=[12, 6])
spr = 1
spc = 2
spn = 0

sep('regression')
spn += 1
plt.subplot(spr, spc, spn)
plt.scatter(x_data, y_data)
plt_x = np.array([x_data.min(), x_data.max()])
plt_y = plt_x * w_v + b_v
plt.plot(plt_x, plt_y, 'r-')

sep('history of cost function value')
spn += 1
plt.subplot(spr, spc, spn)
plt.plot(j_his, label='Cost function')
plt.legend()

sep('Finally show all plotting')
plt.show()
